home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 11 / Cream of the Crop 11-1.iso / games / ted5.zip / TED5-4.C < prev    next >
C/C++ Source or Header  |  1994-02-16  |  56KB  |  2,634 lines

  1. ////////////////////////////////////////////////////
  2. ////////////////////////////////////////////////////
  3. //
  4. // TED5-4
  5. //
  6. ////////////////////////////////////////////////////
  7. ////////////////////////////////////////////////////
  8. #include "ted5.h"
  9. #pragma hdrstop
  10.  
  11.  
  12. void SignalSound(void)
  13. {
  14.  int i;
  15.  
  16.  for(i=0;i<10;i++)
  17.  {
  18.   sound(500+i*500);
  19.   delay(5);
  20.   nosound();
  21.  }
  22. }
  23.  
  24.  
  25. ////////////////////////////////////////////////////
  26. //
  27. // Create an OBJ linkable file from any type of datafile
  28. //
  29. // Exit:
  30. //  0 = everything's a-ok!
  31. // -1 = file not found
  32. // -2 = file >64K
  33. //
  34. ////////////////////////////////////////////////////
  35. int MakeOBJ(char *filename,char *destfilename,char *public,segtype whichseg,char *farname)
  36. {
  37.  char THEADR[17]={0x80,14,0,12,32,32,32,32,32,32,32,32,32,32,32,32,0},
  38.       COMENT[18]={0x88,0,0,0,0,'M','a','k','e','O','B','J',' ','v','1','.','1',0},
  39.       LNAMES[42]={0x96,0,0,
  40.           6,'D','G','R','O','U','P',
  41.           5,'_','D','A','T','A',
  42.           4,'D','A','T','A',
  43.           0,
  44.           5,'_','T','E','X','T',
  45.           4,'C','O','D','E',
  46.           8,'F','A','R','_','D','A','T','A'},
  47.       SEGDEF[9]={0x98,7,0,0x48,0,0,2,3,4},    // for .DATA
  48.       SEGDEF1[9]={0x98,7,0,0x48,0,0,5,6,4},    // for .CODE
  49.       SEGDEF2[9]={0x98,7,0,0x60,0,0,8,7,4},    // for .FARDATA
  50.       GRPDEF[7]={0x9a,4,0,1,0xff,1,0x61},
  51.       MODEND[5]={0x8a,2,0,0,0x74};
  52.  
  53.  unsigned i,j,flag,handle;
  54.  long fsize,offset,loffset,temp,amtleft,amount,offset1;
  55.  char _seg *dblock,*block;
  56.  
  57.  
  58.  //
  59.  // Need to compute the CHECKSUM in the COMENT field
  60.  // (so if the "MakeOBJ..." string is modified, the CHECKSUM
  61.  //  will be correct).
  62.  //
  63.  COMENT[1]=sizeof(COMENT)-3;
  64.  for (flag=i=0;i<sizeof(COMENT);i++)
  65.     flag+=COMENT[i];
  66.  COMENT[sizeof(COMENT)-1]=(flag^0xff)+1;
  67.  
  68.  if ((handle=open(filename,O_BINARY))==NULL)
  69.    return -1;
  70.  
  71.  fsize=filelength(handle);
  72.  close(handle);
  73.  if (fsize>0x10000L)        // BIGGER THAN 1 SEG = ERROR!
  74.    return -2;
  75.  
  76.  LoadIn(filename,(memptr *)&block);    // LOAD FILE IN
  77.  offset=0;
  78.  
  79.  MMAllocate((memptr *)&dblock,0x10000L);
  80.  
  81.  ////////////////////////////////////////////////////
  82.  //
  83.  // INSERT HEADER RECORD
  84.  //
  85.  movedata(_DS,FP_OFF(&THEADR),(unsigned)dblock,offset,sizeof(THEADR));
  86.  movedata(FP_SEG(filename),FP_OFF(filename),
  87.       (unsigned)dblock,offset+4,strlen(filename));
  88.  offset+=sizeof(THEADR);
  89.  
  90.  
  91.  ////////////////////////////////////////////////////
  92.  //
  93.  // INSERT COMMENT RECORD
  94.  //
  95.  movedata(_DS,FP_OFF(COMENT),(unsigned)dblock,offset,sizeof(COMENT));
  96.  offset+=sizeof(COMENT);
  97.  
  98.  
  99.  ////////////////////////////////////////////////////
  100.  //
  101.  // INSERT START OF LIST-OF-NAMES RECORD
  102.  //
  103.  loffset=offset;
  104.  movedata(_DS,FP_OFF(LNAMES),(unsigned)dblock,offset,sizeof(LNAMES));
  105.  offset+=sizeof(LNAMES);
  106.  
  107.  // If it's a .FARDATA segment, we need to insert the segment name!
  108.  if (whichseg==FARDATA)
  109.    {
  110.     *(dblock+offset)=strlen(farname);
  111.     movedata(FP_SEG(farname),FP_OFF(farname),
  112.     (unsigned)dblock,offset+1,strlen(farname));
  113.     offset+=strlen(farname)+1;
  114.    }
  115.  
  116.  // Now, finish the List-Of-Names record by creating
  117.  // the CHECKSUM and LENGTH
  118.  temp=offset;
  119.  offset=offset-loffset-2;
  120.  *(int huge *)(dblock+loffset+1)=offset;
  121.  offset=temp;
  122.  
  123.  // Now, figure out the CHECKSUM of the record
  124.  for (flag=i=0;i<(offset-loffset);i++)
  125.    flag+=*(dblock+i+loffset);
  126.  *(dblock+offset)=(flag^0xff)+1;
  127.  offset++;
  128.  
  129.  
  130.  ////////////////////////////////////////////////////
  131.  //
  132.  // CREATE SEGMENT DEFINITION RECORD
  133.  //
  134.  loffset=offset;
  135.  temp=fsize;
  136.  switch(whichseg)
  137.  {
  138.   case DATA:
  139.     movedata(FP_SEG(&SEGDEF),FP_OFF(&SEGDEF),
  140.          (unsigned)dblock,offset,sizeof(SEGDEF));
  141.     *(int huge *)(dblock+offset+4)=temp;
  142.     offset+=sizeof(SEGDEF);
  143.     break;
  144.   case CODE:
  145.     movedata(FP_SEG(&SEGDEF1),FP_OFF(&SEGDEF1),
  146.          (unsigned)dblock,offset,sizeof(SEGDEF1));
  147.     *(int huge *)(dblock+offset+4)=temp;
  148.     offset+=sizeof(SEGDEF1);
  149.     break;
  150.   case FARDATA:
  151.     movedata(FP_SEG(&SEGDEF2),FP_OFF(&SEGDEF2),
  152.          (unsigned)dblock,offset,sizeof(SEGDEF2));
  153.     *(int huge *)(dblock+offset+4)=temp;
  154.     offset+=sizeof(SEGDEF2);
  155.     break;
  156.  }
  157.  
  158.  // CHECKSUM
  159.  for (flag=0,i=loffset;i<offset;i++)
  160.    flag+=*(dblock+i);
  161.  *(dblock+offset)=(flag^0xff)+1;
  162.  offset++;
  163.  
  164.  
  165.  ////////////////////////////////////////////////////
  166.  //
  167.  // CREATE GROUP DEFINITION RECORD
  168.  //
  169.  switch(whichseg)
  170.  {
  171.   case DATA:
  172.   case CODE:
  173.     movedata(FP_SEG(&GRPDEF),FP_OFF(&GRPDEF),
  174.          (unsigned)dblock,offset,sizeof(GRPDEF));
  175.     offset+=sizeof(GRPDEF);
  176.  }
  177.  
  178.  
  179.  ////////////////////////////////////////////////////
  180.  //
  181.  // CREATE PUBLIC DEFINITION RECORD
  182.  //
  183.  loffset=offset;
  184.  *(dblock+offset)=0x90;        // PUBDEF ID
  185.  offset+=3;            // point to public base, skip length
  186.  *(dblock+offset)=1;        // group index=1
  187.  *(dblock+offset+1)=1;        // segment index=1
  188.  offset+=2;            // point to public name
  189.  
  190.  temp=0;
  191.  movedata(FP_SEG(public),FP_OFF(public),
  192.       (unsigned)dblock,offset+1,strlen(public));
  193.  *(dblock+offset)=strlen(public);
  194.  offset+=strlen(public)+1;
  195.  *(int huge *)(dblock+offset)=0;    // public offset within segment
  196.  offset+=2;
  197.  *(dblock+offset)=0;        // type index
  198.  offset++;
  199.  
  200.  // LENGTH
  201.  temp=offset-loffset-2;
  202.  *(int huge *)(dblock+loffset+1)=temp;
  203.  offset++;
  204.  
  205.  // CHECKSUM
  206.  for (flag=0,i=loffset;i<offset;i++)
  207.    flag+=*(dblock+i);
  208.  *(dblock+offset)=(flag^0xff)+1;
  209.  
  210.  
  211.  ////////////////////////////////////////////////////
  212.  //
  213.  // DATA RECORD(S). YUCK.
  214.  //
  215.  
  216.  amtleft=fsize;
  217.  amount=1024;
  218.  for (i=0;i<(fsize+1023)/1024;i++)
  219.    {
  220.     offset1=offset;
  221.     if (amtleft<1024)
  222.       amount=amtleft;
  223.     //
  224.     // RECORD HEADER
  225.     //
  226.     *(dblock+offset)=0xa0;            // LEDATA ID
  227.     *(int huge *)(dblock+offset+1)=amount+4;    // length of record
  228.     offset+=3;
  229.     *(dblock+offset)=1;                // segment index
  230.     *(int huge *)(dblock+offset+1)=i*1024;    // index into segment
  231.     offset+=3;
  232.     //
  233.     // LOAD DATA IN
  234.     //
  235.     LoadFile(filename,(char huge *)dblock+offset,i*1024,amount);
  236.     offset+=amount;
  237.     //
  238.     // CHECKSUM!
  239.     //
  240.     for (flag=0,j=offset1;j<offset;j++)
  241.       flag+=*(dblock+j);
  242.     *(dblock+offset)=(flag^0xff)+1;
  243.     offset++;
  244.  
  245.     amtleft-=1024;
  246.    }
  247.  
  248.  ////////////////////////////////////////////////////
  249.  //
  250.  // MODULE END! YES!
  251.  //
  252.  movedata(FP_SEG(&MODEND),FP_OFF(&MODEND),(unsigned)dblock,offset,sizeof(MODEND));
  253.  offset+=sizeof(MODEND);
  254.  
  255.  //
  256.  // Save the little puppy out!
  257.  //
  258.  SaveFile(destfilename,(char huge *)dblock,0,offset);
  259.  MMFreePtr((memptr *)&dblock);
  260.  MMFreePtr((memptr *)&block);
  261.  return 0;
  262. }
  263.  
  264.  
  265. ////////////////////////////////////////////////////
  266. //
  267. // DUMP THE PASTE BUFFER OUT TO EITHER AN
  268. // "APPLE PREFERRED" OR "ILBM" GRAPHICS FORMAT FILE
  269. //
  270. // NOTE: THIS IS ONLY AVAILABLE IN EGA, BECAUSE I
  271. // DON'T FEEL LIKE WRITING A CGA ILBM PIXEL-SPLICER --
  272. // AND APPLE PREFERRED ONLY HANDLES 4-BIT COLOR ANYWAY!
  273. // (YES, I KNOW, I COULD ONLY USE 4 OUT OF 16 COLORS...SHUT UP!)
  274. //
  275. ////////////////////////////////////////////////////
  276. btype dumpB[]={{" DeluxePaint II ILBM ",4,2,2},
  277.            {"   Apple Preferred   ",4,5,1}},
  278.       fnameB={"         ",4,3,1};
  279. DialogDef dumpD={" Which format do you require?",30,7,2,&dumpB[0],NULL},
  280.       fnameD={"Enter filename to\nsave (no suffix)",17,5,1,&fnameB,NULL};
  281.  
  282. void Item_GraphicDump(void)
  283. {
  284.  char filename[14],ext[5],_seg *block,_seg *block1;
  285.  ApPrefStr PrefHeader;
  286.  int which,i,j,k,m,n,pwidth,lwidth,dx,dy;
  287.  long tilelen,fsize=0,bufsize;
  288.  
  289.  if (!PasteOK)
  290.    {
  291.     ErrDialog("You need to use the Copy command\n"
  292.           "to copy part of the map or tiles\n"
  293.           "so I know what I need to dump!"," OK ");
  294.     return;
  295.    }
  296.  
  297.  switch(videomode)
  298.  {
  299.   case CGA:
  300.   case VGA:
  301.     ErrDialog("Sorry, but this function is only\n"
  302.           "available for EGA mode.  If you\n"
  303.           "have a REAL NEED for this to work\n"
  304.           "in CGA or VGA, talk to Id Software!"," OK ");
  305.     return;
  306.  }
  307.  
  308.  if (!(which=DoDialog(&dumpD)))
  309.    return;
  310.  
  311.  //
  312.  // SET TILE LENGTH
  313.  //
  314.  switch(tsize)
  315.  {
  316.   case 1: tilelen=32L; break;
  317.   case 2: tilelen=128L; break;
  318.   case 3: tilelen=512L;
  319.  }
  320.  
  321.  //
  322.  // GET FILENAME TO SAVE UNDER
  323.  //
  324.  DrawDialog(&fnameD,1);
  325.  MouseHide();
  326.  GetButtonXY(&fnameD,0,&sx,&sy);
  327.  if (!input(filename,8))
  328.    {
  329.     RestoreBackground();
  330.     MouseShow();
  331.     return;
  332.    }
  333.  for (i=0;i<strlen(filename);i++)
  334.    if (filename[i]=='.')
  335.      {
  336.       filename[i]=0;
  337.       break;
  338.      }
  339.  RestoreBackground();
  340.  MouseShow();
  341.  
  342.  //
  343.  // SETUP FOR EACH TYPE
  344.  //
  345.  switch(which)
  346.  {
  347.   case 1:    // ILBM
  348.     {
  349.      long size;
  350.      char form[5]="FORM",ilbm[9]="ILBMBMHD",body[5]="BODY";
  351.  
  352.  
  353.      size=48L;
  354.      MMAllocate((memptr *)&block,size);
  355.  
  356.      movedata(FP_SEG(form),FP_OFF(form),(unsigned)block,fsize,4);
  357.      fsize+=4;
  358.      size=40L+tilelen*TileCopy.w*TileCopy.h;
  359.      *(block+fsize)=(size>>24)&0xff;
  360.      *(block+fsize+1)=(size>>16)&0xff;
  361.      *(block+fsize+2)=(size>>8)&0xff;
  362.      *(block+fsize+3)=size&0xff;
  363.      fsize+=4;
  364.      movedata(FP_SEG(ilbm),FP_OFF(ilbm),(unsigned)block,fsize,8);
  365.      fsize+=8;
  366.      *(block+fsize)=0;
  367.      *(block+fsize+1)=0;
  368.      *(block+fsize+2)=0;
  369.      *(block+fsize+3)=20;
  370.      fsize+=4;
  371.      *(block+fsize)=(TileCopy.w<<(tsize+2))/256;   // pixel width
  372.      *(block+fsize+1)=(TileCopy.w<<(tsize+2))&0xff;
  373.      *(block+fsize+2)=(TileCopy.h<<(tsize+2))/256; // pixel height
  374.      *(block+fsize+3)=(TileCopy.h<<(tsize+2))&0xff;
  375.      *(int huge *)(block+fsize+4)=0;        // Xorg
  376.      *(int huge *)(block+fsize+6)=0;        // Yorg
  377.      *(block+fsize+8)=4;            // planes
  378.      *(block+fsize+9)=0;            // mask (stencil!)
  379.      *(block+fsize+10)=0;            // compression (none)
  380.      *(block+fsize+11)=0;            // pad (?)
  381.      *(int huge *)(block+fsize+12)=0;        // trans (?)
  382.      *(int huge *)(block+fsize+14)=0x101;    // aspt (aspect?)
  383.      *(int huge *)(block+fsize+16)=0x4001;    // page width
  384.      *(int huge *)(block+fsize+18)=0xc800;    // page height
  385.      fsize+=20;
  386.      movedata(FP_SEG(body),FP_OFF(body),(unsigned)block,fsize,4);
  387.      fsize+=4;
  388.      size=tilelen*TileCopy.w*TileCopy.h;
  389.      *(block+fsize)=(size>>24)&0xff;
  390.      *(block+fsize+1)=(size>>16)&0xff;
  391.      *(block+fsize+2)=(size>>8)&0xff;
  392.      *(block+fsize+3)=size&0xff;
  393.      fsize+=4;
  394.  
  395.      strcpy(ext,".LBM");
  396.     }
  397.     break;
  398.  
  399.   case 2:    // APPLE PREFERRED
  400.     {
  401.      int Ctable[16]={0x0000,0x000a,0x00a0,0x00aa,0x0a00,0x0a0a,0x0a50,0x0aaa,
  402.              0x0555,0x055f,0x05f5,0x05ff,0x0f55,0x0f5f,0x0ff5,0x0fff};
  403.      long size,pixwid;
  404.  
  405.  
  406.      PrefHeader.length=sizeof(ApPrefStr)+4L*(TileCopy.h<<(tsize+2))+
  407.     TileCopy.w*TileCopy.h*tilelen+(((TileCopy.w*TileCopy.h*tilelen)+63)/64);
  408.      strncpy(PrefHeader.Kind,"\x4MAIN",5);
  409.      PrefHeader.MasterMode=0;
  410.      PrefHeader.PixelsPerLine=TileCopy.w<<(tsize+2);
  411.      PrefHeader.NumColorTables=1;
  412.      for (i=0;i<16;i++)
  413.        PrefHeader.ColorTable[i]=Ctable[i];
  414.      PrefHeader.NumScanLines=TileCopy.h<<(tsize+2);
  415.  
  416.      size=sizeof(ApPrefStr)+4L*(TileCopy.h<<(tsize+2));
  417.      MMAllocate((memptr *)&block,size);
  418.      movedata(FP_SEG(&PrefHeader),FP_OFF(&PrefHeader),(unsigned)block,fsize,sizeof(ApPrefStr));
  419.      fsize+=sizeof(ApPrefStr);
  420.  
  421.      pixwid=TileCopy.w*(2<<tsize);
  422.      for (i=0;i<(TileCopy.h<<(tsize+2));i++)
  423.        {
  424.     *(int huge *)(block+fsize)=pixwid+(pixwid+63)/64;
  425.     *(int huge *)(block+fsize+2)=0;
  426.     fsize+=4;
  427.        }
  428.  
  429.      strcpy(ext,".APP");
  430.      MMAllocate((memptr *)&block1,tilelen*TileCopy.w);
  431.     }
  432.  }
  433.  
  434.  //
  435.  // SAVE HEADER OUT
  436.  //
  437.  strcat(filename,ext);
  438.  SaveFile(filename,(char huge *)block,0,fsize);
  439.  MMFreePtr((memptr *)&block);
  440.  
  441.  //
  442.  // NOW, WRITE THE DATA OUT! EEEE!
  443.  //
  444.  bufsize=tilelen*TileCopy.w;
  445.  MMAllocate((memptr *)&block,bufsize);
  446.  
  447.  pwidth=(1<<(tsize-1))*TileCopy.w;
  448.  lwidth=pwidth*4;
  449.  
  450.  ErrDialog("One moment. I am busy.\n     Countdown:","");
  451.  dx=sx;
  452.  dy=sy;
  453.  
  454.  for (j=0;j<TileCopy.h;j++)
  455.    {
  456.     sx=dx;
  457.     sy=dy;
  458.     printint(TileCopy.h-j);
  459.     print(" ");
  460.  
  461.     for (i=0;i<TileCopy.w;i++)
  462.       {
  463.        unsigned tilet,tilem,tilei,loc;
  464.  
  465.        //
  466.        // ESC out?
  467.        //
  468.        if (keydown[1])
  469.      {
  470.       RestoreBackground();
  471.       while(keydown[1]);
  472.       ErrDialog("You aborted out of the\n"
  473.             "graphic dump conversion!"," Yes, I know ");
  474.  
  475.       if (which==2)
  476.         MMFreePtr((memptr *)&block1);
  477.       return;
  478.      }
  479.        //
  480.        // GET THE CORRECT TILE MOVED INTO "TDATA"
  481.        //
  482.        switch(TileCopy.MapOrTileSelect)
  483.        {
  484.     case 0:    // MAP COPY
  485.       loc=(j+TileCopy.y)*mapwidth+TileCopy.x+i;
  486.       tilet=(TileCopy.PlanesCopied&BPLANE)?CutBkgnd[loc]:-BkgndColor;
  487.       tilem=(TileCopy.PlanesCopied&FPLANE)?CutFrgnd[loc]+tilenum:0;
  488.       tilei=(TileCopy.PlanesCopied&IPLANE)?CutInfoPl[loc]+tilenum:0;
  489.       CombineTiles(tilet,tilem,tilei,tsize);
  490.       break;
  491.     case 1:    // BKGND TILE COPY
  492.       loc=(TileCopy.y+j)*selectcols+TileCopy.x+i;
  493.       CombineTiles(loc,0,0,tsize);
  494.       break;
  495.     case 2:    // FRGND TILE COPY
  496.       loc=(TileCopy.y+j)*selectcols+TileCopy.x+i+tilenum;
  497.       CombineTiles(-BkgndColor,loc,0,tsize);
  498.        }
  499.  
  500.        //
  501.        // NOW, MUNGE "TDATA" INTO BIT-PLANES!
  502.        //
  503.        // INTERNAL:        P0    P1    P2    P3
  504.        //    SCANLINE x    ......    ......    ......    ......
  505.        //
  506.        for (k=0;k<8<<(tsize-1);k++)
  507.      for (m=0;m<4;m++)
  508.        movedata(FP_SEG(&tdata),FP_OFF(&tdata)+(m*tsize*(8<<(tsize-1)))+k*(1<<(tsize-1)),
  509.         (unsigned)block,k*lwidth+m*pwidth+i*(1<<(tsize-1)),1<<(tsize-1));
  510.       }
  511.     //
  512.     // ALRIGHT. NOW SAVE THIS CHUNK OUT IN THE CORRECT FORMAT
  513.     //
  514.     switch(which)
  515.     {
  516.      case 1:    // ILBM
  517.        SaveFile(filename,MK_FP(block,0),fsize,bufsize);
  518.        fsize+=bufsize;
  519.        break;
  520.      case 2:    // APPLE PREFERRED
  521.        {
  522.     int len,clen;
  523.  
  524.     //
  525.     // FIRST, I NEED TO CONVERT THE ILBM PLANAR FORMAT
  526.     // TO SUPER-RES NIBBLES
  527.     //
  528.     for (k=0;k<8<<(tsize-1);k++)
  529.       for (m=0;m<(1<<(tsize-1))*TileCopy.w;m++)
  530.         {
  531.          unsigned char src[4],dest[4]={0,0,0,0};
  532.  
  533.          for (n=0;n<4;n++)
  534.            src[n]=block[k*lwidth+pwidth*n+m];
  535.  
  536.          asm    mov    al,[BYTE PTR src+0]
  537.          asm    mov    ah,[BYTE PTR src+1]
  538.          asm    mov    bl,[BYTE PTR src+2]
  539.          asm    mov    bh,[BYTE PTR src+3]
  540.  
  541.          // dest[0]
  542.          asm    shl    bh,1
  543.          asm    rcl    cl,1
  544.          asm    shl    bl,1
  545.          asm    rcl    cl,1
  546.          asm    shl    ah,1
  547.          asm    rcl    cl,1
  548.          asm    shl    al,1
  549.          asm    rcl    cl,1
  550.  
  551.          asm    shl    bh,1
  552.          asm    rcl    cl,1
  553.          asm    shl    bl,1
  554.          asm    rcl    cl,1
  555.          asm    shl    ah,1
  556.          asm    rcl    cl,1
  557.          asm    shl    al,1
  558.          asm    rcl    cl,1
  559.  
  560.          // dest[1]
  561.          asm    shl    bh,1
  562.          asm    rcl    ch,1
  563.          asm    shl    bl,1
  564.          asm    rcl    ch,1
  565.          asm    shl    ah,1
  566.          asm    rcl    ch,1
  567.          asm    shl    al,1
  568.          asm    rcl    ch,1
  569.  
  570.          asm    shl    bh,1
  571.          asm    rcl    ch,1
  572.          asm    shl    bl,1
  573.          asm    rcl    ch,1
  574.          asm    shl    ah,1
  575.          asm    rcl    ch,1
  576.          asm    shl    al,1
  577.          asm    rcl    ch,1
  578.  
  579.          // dest[2]
  580.          asm    shl    bh,1
  581.          asm    rcl    dl,1
  582.          asm    shl    bl,1
  583.          asm    rcl    dl,1
  584.          asm    shl    ah,1
  585.          asm    rcl    dl,1
  586.          asm    shl    al,1
  587.          asm    rcl    dl,1
  588.  
  589.          asm    shl    bh,1
  590.          asm    rcl    dl,1
  591.          asm    shl    bl,1
  592.          asm    rcl    dl,1
  593.          asm    shl    ah,1
  594.          asm    rcl    dl,1
  595.          asm    shl    al,1
  596.          asm    rcl    dl,1
  597.  
  598.          // dest[3]
  599.          asm    shl    bh,1
  600.          asm    rcl    dh,1
  601.          asm    shl    bl,1
  602.          asm    rcl    dh,1
  603.          asm    shl    ah,1
  604.          asm    rcl    dh,1
  605.          asm    shl    al,1
  606.          asm    rcl    dh,1
  607.  
  608.          asm    shl    bh,1
  609.          asm    rcl    dh,1
  610.          asm    shl    bl,1
  611.          asm    rcl    dh,1
  612.          asm    shl    ah,1
  613.          asm    rcl    dh,1
  614.          asm    shl    al,1
  615.          asm    rcl    dh,1
  616.  
  617.          asm    mov    [BYTE PTR dest+0],cl
  618.          asm    mov    [BYTE PTR dest+1],ch
  619.          asm    mov    [BYTE PTR dest+2],dl
  620.          asm    mov    [BYTE PTR dest+3],dh
  621.  
  622.          movedata(FP_SEG(&dest),FP_OFF(&dest),
  623.         (unsigned)block1,k*lwidth+m*4,4);
  624.         }
  625.  
  626.     //
  627.     // NOW, TIME TO WRITE THE DATA OUT IN 64-BYTE CHUNKS! YUCK!
  628.     //
  629.     for (k=0;k<8<<(tsize-1);k++)
  630.       {
  631.        char clen;
  632.        int off=k*lwidth;;
  633.  
  634.        len=4*pwidth;
  635.        while(len>0)
  636.        {
  637.         if (len>64)
  638.           clen=64;
  639.         else
  640.           clen=len;
  641.  
  642.         clen--;
  643.         SaveFile(filename,(char huge *)&clen,fsize++,1);
  644.         clen++;
  645.  
  646.         SaveFile(filename,MK_FP(block1,off),fsize,clen);
  647.         fsize+=clen;
  648.         off+=clen;
  649.         len-=clen;
  650.        }
  651.       }
  652.        }
  653.     }
  654.    }
  655.  
  656.  if (which==2)
  657.    MMFreePtr((memptr *)&block1);
  658.  
  659.  MMFreePtr((memptr *)&block);
  660.  RestoreBackground();
  661.  
  662.  ErrDialog("Graphic successfully dumped!"," Yeah! ");
  663. }
  664.  
  665.  
  666. ////////////////////////////////////////////////////
  667. //
  668. // Item - Edit TILEINFO/M values
  669. //
  670. ////////////////////////////////////////////////////
  671. btype ETVb[]={{" Tileinfo ",2,21,1},
  672.           {" TileinfoM ",16,21,1},
  673.           {" Exit ",30,21,2}};
  674. DialogDef ETVd={"       Edit TILEINFO/M values",38,23,3,&ETVb[0],NULL};
  675. int CurTIvalue;
  676.  
  677. void Item_EditTinfoValues(void)
  678. {
  679.  int max,i,which,exitok=0,mx,my,b0,b1,CTRLdown;
  680.  static int whichtinfo=0;
  681.  
  682.  //
  683.  // IS THE "CTRL" KEY DOWN?
  684.  //
  685.  CTRLdown=keydown[0x1d];
  686.  if (CTRLdown)
  687.    {
  688.     if (planeton)
  689.       whichtinfo=0;
  690.     else
  691.       whichtinfo=1;
  692.    }
  693.  
  694.  switch(whichtinfo)
  695.  {
  696.   case 0: max=tilenum; break;
  697.   case 1: max=tilemnum;
  698.  }
  699.  
  700.  switch(videomode)
  701.  {
  702.   case CGA:
  703.   case EGA1:
  704.   case VGA:
  705.     ETVd.height=23;
  706.     for(i=0;i<3;i++)
  707.       ETVb[i].yoff=21;
  708.     break;
  709.   case EGA2:
  710.     ETVd.height=58;
  711.     for(i=0;i<3;i++)
  712.       ETVb[i].yoff=56;
  713.  }
  714.  
  715.  //
  716.  // DRAW THE SCREEN
  717.  //
  718.  DrawDialog(&ETVd,1);
  719.  if (CTRLdown)
  720.    {
  721.     DrawTinfoScreen(whichtinfo,0,-max);    // ALIGN TO TOP
  722.     switch(whichtinfo)
  723.     {
  724.      case 0: DrawTinfoScreen(whichtinfo,0,whicht); break;
  725.      case 1: DrawTinfoScreen(whichtinfo,0,whichtm-tilenum);
  726.     }
  727.    }
  728.  else
  729.    DrawTinfoScreen(whichtinfo,0,0);
  730.  
  731.  
  732.  do
  733.  {
  734.   which=CheckButtonsRet(&ETVd);
  735.   if (which>=0)
  736.     switch(which)
  737.     {
  738.      case 0:
  739.        RestoreBackground();
  740.        return;
  741.      case 1:
  742.        if (whichtinfo)
  743.      {
  744.       max=tilenum;
  745.       whichtinfo=0;
  746.       DrawDialog(&ETVd,0);
  747.       DrawTinfoScreen(whichtinfo,0,0);
  748.      }
  749.        else
  750.      {
  751.       GetButtonXY(&ETVd,0,&sx,&sy);
  752.       MouseHide();
  753.       print(ETVb[0].text);
  754.       MouseShow();
  755.       errsound();
  756.      }
  757.        break;
  758.      case 2:
  759.        if (!tilemnum)
  760.      {
  761.       GetButtonXY(&ETVd,1,&sx,&sy);
  762.       MouseHide();
  763.       print(ETVb[1].text);
  764.       MouseShow();
  765.       errsound();
  766.       break;
  767.      }
  768.  
  769.        if (!whichtinfo)
  770.      {
  771.       max=tilemnum;
  772.       whichtinfo=1;
  773.       DrawDialog(&ETVd,0);
  774.       DrawTinfoScreen(whichtinfo,0,0);
  775.      }
  776.        else
  777.      {
  778.       GetButtonXY(&ETVd,1,&sx,&sy);
  779.       MouseHide();
  780.       print(ETVb[1].text);
  781.       MouseShow();
  782.       errsound();
  783.      }
  784.        break;
  785.  
  786.      case 3:
  787.        exitok=1;
  788.     }
  789.   else
  790.     {
  791.      MouseCoords(&mx,&my);
  792.      mx/=8;
  793.      my/=8;
  794.      b0=MouseButton()&1;
  795.      b1=MouseButton()&2;
  796.  
  797.      //
  798.      // CHECK FOR BUTTON PRESSES
  799.      //
  800.      if (b0)
  801.        UseTinfoValue(whichtinfo,mx,my,1);
  802.      else
  803.      if (b1)
  804.        UseTinfoValue(whichtinfo,mx,my,0);
  805.  
  806.      //
  807.      // SPACE = ENTER VALUES HORIZONTALLY
  808.      //
  809.      if (keydown[0x39])
  810.      {
  811.       while(keydown[0x39]);
  812.       clearkeys();
  813.       EnterTinfoValue(whichtinfo,mx,my,0);
  814.      }
  815.  
  816.      //
  817.      // CHECK FOR SCROLLING
  818.      //
  819.      if (keydown[0x48])        // UP
  820.        {
  821.     DrawTinfoScreen(whichtinfo,0,-1);
  822.     if (keydown[0x1d])
  823.       while(keydown[0x48]);
  824.        }
  825.      else
  826.      if (keydown[0x50])        // DOWN
  827.        {
  828.     DrawTinfoScreen(whichtinfo,0,1);
  829.     if (keydown[0x1d])
  830.       while(keydown[0x50]);
  831.        }
  832.      else
  833.      if (keydown[0x49])        // PGUP
  834.        {
  835.     DrawTinfoScreen(whichtinfo,0,-8);
  836.     if (!keydown[0x1d])
  837.       while(keydown[0x49]);
  838.        }
  839.      else
  840.      if (keydown[0x51])        // PGDN
  841.        {
  842.     DrawTinfoScreen(whichtinfo,0,8);
  843.     if (!keydown[0x1d])
  844.       while(keydown[0x51]);
  845.        }
  846.      else
  847.      if (keydown[0x47])        // HOME
  848.        {
  849.     DrawTinfoScreen(whichtinfo,0,-max);
  850.     while(keydown[0x47]);
  851.        }
  852.      else
  853.      if (keydown[0x4f])        // END
  854.        {
  855.     DrawTinfoScreen(whichtinfo,0,max);
  856.     while(keydown[0x4f]);
  857.        }
  858.      else
  859.      if (keydown[0x4d])        // RIGHT
  860.        {
  861.     DrawTinfoScreen(whichtinfo,1,0);
  862.     if (!keydown[0x1d])
  863.       while(keydown[0x4d]);
  864.        }
  865.      else
  866.      if (keydown[0x4b])        // LEFT
  867.        {
  868.     DrawTinfoScreen(whichtinfo,-1,0);
  869.     if (!keydown[0x1d])
  870.       while(keydown[0x4b]);
  871.        }
  872.  
  873.     }
  874.  
  875.  } while(!exitok);
  876.  
  877.  RestoreBackground();
  878. }
  879.  
  880.  
  881. //
  882. // PICKUP/DROP TILEINFO VALUE AT CURSOR
  883. //
  884. void UseTinfoValue(int whichtinfo,int mx,int my,int PickupOrDrop)
  885. {
  886.  int whichx=-1,whichy=-1;
  887.  unsigned dialogx,dialogy;
  888.  
  889.  
  890.  GetDialogXY(&ETVd,&dialogx,&dialogy);
  891.  
  892.  if (mx>=dialogx+10 && mx<=dialogx+45)
  893.    whichx=(mx-(dialogx+10))/7;
  894.  
  895.  if (my>=4 && my<=((videomode==EGA2)?55:19))
  896.    whichy=(my-4)>>(tsize-1);
  897.  
  898.  switch(whichtinfo)
  899.  {
  900.   case 0:
  901.     if (whichx>=numtplanes)
  902.       whichx=-1;
  903.     if (whichy>=tilenum)
  904.       whichy=-1;
  905.     break;
  906.  
  907.   case 1:
  908.     if (whichx>=numtmplanes)
  909.       whichx=-1;
  910.     if (whichy>=tilemnum)
  911.       whichy=-1;
  912.  }
  913.  
  914.  if (whichx>=0 && whichy>=0)
  915.  {
  916.   if (!PickupOrDrop)
  917.     switch(whichtinfo)
  918.     {
  919.      case 0:    // TILE
  920.        CurTIvalue=*(Tinfo[whichx+TIxbase]+whichy+TIybase);
  921.        break;
  922.      case 1:    // MASKED
  923.        CurTIvalue=*(TMinfo[whichx+TIxmbase]+whichy+TIymbase);
  924.     }
  925.   else
  926.     switch(whichtinfo)
  927.     {
  928.      case 0:    // TILE
  929.        *(Tinfo[whichx+TIxbase]+whichy+TIybase)=CurTIvalue;
  930.        DirtyFlag=1;
  931.        break;
  932.      case 1:    // MASKED
  933.        *(TMinfo[whichx+TIxmbase]+whichy+TIymbase)=CurTIvalue;
  934.        DirtyFlag=1;
  935.     }
  936.  
  937.   DrawTinfoScreen(whichtinfo,0,0);
  938.  }
  939.  while(MouseButton());
  940. }
  941.  
  942.  
  943. //
  944. // ENTER TILEINFO/M CELL VALUES
  945. //
  946. void EnterTinfoValue(int whichtinfo,int mx,int my,int H_or_V)
  947. {
  948.  int whichx=-1,whichy=-1,val,outok=0,tempx,tempy,maxx,maxy;
  949.  unsigned dialogx,dialogy;
  950.  
  951.  
  952.  GetDialogXY(&ETVd,&dialogx,&dialogy);
  953.  
  954.  if (mx>=dialogx+10 && mx<=dialogx+45)
  955.    whichx=(mx-(dialogx+10))/7;
  956.  
  957.  if (my>=4 && my<=((videomode==EGA2)?55:19))
  958.    whichy=(my-4)>>(tsize-1);
  959.  
  960.  switch(whichtinfo)
  961.  {
  962.   case 0:
  963.     if (whichx>=numtplanes)
  964.       whichx=-1;
  965.     if (whichy>=tilenum)
  966.       whichy=-1;
  967.     break;
  968.  
  969.   case 1:
  970.     if (whichx>=numtmplanes)
  971.       whichx=-1;
  972.     if (whichy>=tilemnum)
  973.       whichy=-1;
  974.  }
  975.  
  976.  MouseHide();
  977.  
  978.  if (whichx>=0 && whichy>=0)
  979.    do
  980.    {
  981.     //
  982.     // INPUT VALUE
  983.     //
  984.     sx=whichx*7+dialogx+10;
  985.     sy=(whichy<<(tsize-1))+4;
  986.     print("    ");
  987.     sx-=4;
  988.     if ((val=inputint(3))!=(int)ESCOUT)
  989.       switch(whichtinfo)
  990.       {
  991.        case 0:    // TILE
  992.      *(Tinfo[whichx+TIxbase]+whichy+TIybase)=val&0xff;
  993.      DirtyFlag=1;
  994.      break;
  995.        case 1:    // MASKED
  996.      *(TMinfo[whichx+TIxmbase]+whichy+TIymbase)=val&0xff;
  997.      DirtyFlag=1;
  998.       }
  999.     else
  1000.       outok=1;
  1001.  
  1002.     //
  1003.     // INPUT INTO THE NEXT FIELD!
  1004.     //
  1005.     if (!outok)
  1006.       {
  1007.        tempx=(whichtinfo?TIxmbase:TIxbase);
  1008.        tempy=(whichtinfo?TIymbase:TIybase);
  1009.        maxx=(whichtinfo?numtmplanes:numtplanes);
  1010.        maxy=(whichtinfo?tilemnum:tilenum);
  1011.  
  1012.        switch(H_or_V)
  1013.        {
  1014.     case 0:    // HORIZONTAL
  1015.       whichx++;
  1016.       if (tempx+whichx>=maxx)
  1017.         outok=1;
  1018.       else
  1019.       if (whichx>TINFOWIDTH)
  1020.         {
  1021.          whichx=TINFOWIDTH;
  1022.          tempx++;
  1023.          if (tempx>=maxx)
  1024.            outok=1;
  1025.         }
  1026.  
  1027.       switch(whichtinfo)
  1028.       {
  1029.        case 0: TIxbase=tempx; break;
  1030.        case 1: TIxmbase=tempx;
  1031.       }
  1032.       break;
  1033.  
  1034.     case 1:    // VERTICAL
  1035.       whichy++;
  1036.       if (tempy+whichy>=maxy)
  1037.         outok=1;
  1038.       else
  1039.       if (whichy>(videomode==EGA2?TINFOHEIGHTEGA2:TINFOHEIGHT))
  1040.         {
  1041.          whichy=(videomode==EGA2?TINFOHEIGHTEGA2:TINFOHEIGHT);
  1042.          tempy++;
  1043.          if (tempy>=maxy)
  1044.            outok=1;
  1045.         }
  1046.  
  1047.       switch(whichtinfo)
  1048.       {
  1049.        case 0: TIybase=tempy; break;
  1050.        case 1: TIymbase=tempy;
  1051.       }
  1052.        }
  1053.       }
  1054.  
  1055.     DrawTinfoScreen(whichtinfo,0,0);
  1056.  
  1057.    } while (!outok);
  1058.  
  1059.  MouseShow();
  1060. }
  1061.  
  1062.  
  1063.  
  1064. //
  1065. // Draw the Tileinfo screen
  1066. //
  1067. void DrawTinfoScreen(int thescreen,int deltax,int deltay)
  1068. {
  1069.  int temp,temp1,i,j,width,height,dialogx;
  1070.  char _seg *Values[10];
  1071.  
  1072.  
  1073.  MouseHide();
  1074.  switch(videomode)
  1075.  {
  1076.   case CGA:
  1077.   case EGA1:
  1078.   case VGA:
  1079.     dialogx=1;
  1080.     height=16>>(tsize-1); break;
  1081.   case EGA2:
  1082.     dialogx=21;
  1083.     height=52>>(tsize-1);
  1084.  }
  1085.  
  1086.  switch(thescreen)
  1087.  {
  1088.   case 0:    // TILEINFO
  1089.     if (height>tilenum)
  1090.       height=tilenum;
  1091.     else
  1092.       {
  1093.        TIybase+=deltay;
  1094.        if (TIybase<0)
  1095.      TIybase=0;
  1096.        else
  1097.        if (TIybase+height>tilenum)
  1098.      TIybase=tilenum-height;
  1099.       }
  1100.     temp=TIybase;
  1101.     break;
  1102.  
  1103.   case 1:    // TILEINFOM
  1104.     if (height>tilemnum)
  1105.       height=tilemnum;
  1106.     else
  1107.       {
  1108.        TIymbase+=deltay;
  1109.        if (TIymbase<0)
  1110.      TIymbase=0;
  1111.        else
  1112.        if (TIymbase+height>tilemnum)
  1113.      TIymbase=tilemnum-height;
  1114.       }
  1115.     temp=TIymbase;
  1116.  }
  1117.  
  1118.  //
  1119.  // DRAW TILES AND THEIR VALUES
  1120.  //
  1121.  for (i=0;i<height;i++)
  1122.    {
  1123.     sx=dialogx;
  1124.     sy=(i<<(tsize-1))+4;
  1125.     printhex(i+temp);
  1126.     sx=dialogx;
  1127.     sy++;
  1128.     print("    ");
  1129.     sx-=4;
  1130.     printint(i+temp);
  1131.  
  1132.     switch(thescreen)
  1133.     {
  1134.      case 0:
  1135.        CombineTiles(temp+i,0,0,tsize);
  1136.        break;
  1137.      case 1:
  1138.        CombineTiles(-BkgndColor,temp+i+tilenum,0,tsize);
  1139.     }
  1140.  
  1141.     DrawTile(dialogx+5,(i+2)<<(3+(tsize-1)),tsize);
  1142.    }
  1143.  
  1144.  //
  1145.  // DRAW TILEINFO ARRAYS
  1146.  //
  1147.  width=4;
  1148.  
  1149.  switch(thescreen)
  1150.  {
  1151.   case 0:
  1152.     if (width>numtplanes)
  1153.       width=numtplanes;
  1154.     else
  1155.       {
  1156.        TIxbase+=deltax;
  1157.        if (TIxbase<0)
  1158.      TIxbase=0;
  1159.        else
  1160.        if (TIxbase+width>numtplanes)
  1161.      TIxbase=numtplanes-width;
  1162.       }
  1163.     temp1=TIxbase;
  1164.     for (i=0;i<10;i++)
  1165.       Values[i]=Tinfo[i];
  1166.  
  1167.     break;
  1168.  
  1169.   case 1:
  1170.     if (width>numtmplanes)
  1171.       width=numtmplanes;
  1172.     else
  1173.       {
  1174.        TIxmbase+=deltax;
  1175.        if (TIxmbase<0)
  1176.      TIxmbase=0;
  1177.        else
  1178.        if (TIxmbase+width>numtmplanes)
  1179.      TIxmbase=numtmplanes-width;
  1180.       }
  1181.     temp1=TIxmbase;
  1182.     for (i=0;i<10;i++)
  1183.       Values[i]=TMinfo[i];
  1184.  }
  1185.  
  1186.  for (j=0;j<width;j++)
  1187.    {
  1188.     sx=(dialogx+10)+j*7;
  1189.     sy=3;
  1190.     switch(thescreen)
  1191.     {
  1192.      case 0:
  1193.        print("       ");
  1194.        sx-=7;
  1195.        fprint(MapFileHeader->tnames[j+TIxbase]);
  1196.        break;
  1197.      case 1:
  1198.        print("       ");
  1199.        sx-=7;
  1200.        fprint(MapFileHeader->tmnames[j+TIxmbase]);
  1201.     }
  1202.     for (i=0;i<height;i++)
  1203.       {
  1204.        sx=(dialogx+10)+j*7;
  1205.        sy=(i<<(tsize-1))+4;
  1206.        print("$");
  1207.        printhexb(Values[j+temp1][i+temp]);
  1208.        sx=(dialogx+10)+j*7;
  1209.        sy++;
  1210.        print("   ");
  1211.        sx-=3;
  1212.        printint(Values[j+temp1][i+temp]&0xff);
  1213.       }
  1214.    }
  1215.  MouseShow();
  1216. }
  1217.  
  1218.  
  1219.  
  1220. ////////////////////////////////////////////////////
  1221. //
  1222. // Item - Add or Delete TILEINFO/M planes
  1223. //
  1224. ////////////////////////////////////////////////////
  1225. btype AODb[]={{" Add ",1,3,1},
  1226.           {" Delete ",8,3,1},
  1227.           {" Exit ",18,3,2}},
  1228.       TOMb[]={{" Tileinfo  ",1,2,1},
  1229.           {" TileinfoM ",1,5,1}},
  1230.       AreSureB2[]={{" Yes ",1,2,1},
  1231.            {" No ",8,2,2}},
  1232.       TINb2={" Done ",8,15,1};;
  1233. DialogDef AODd={"       TILEINFO/M\n     Pick a function",25,5,3,&AODb[0],NULL},
  1234.       TOMd={"Add to what?",13,7,2,&TOMb[0],NULL},
  1235.       NId={"Gimme a name!",13,4,0,NULL,NULL},
  1236.       AreSureD2={"Are you sure?",13,4,2,&AreSureB2[0],NULL},
  1237.       TINd2={"   Which to delete?\n"
  1238.         " TILEINFO   TILEINFOM",
  1239.         22,17,1,&TINb2,NULL};
  1240.  
  1241. void Item_AddDelTinfo(void)
  1242. {
  1243.  char temp[16];
  1244.  int which,i;
  1245.  unsigned dx,dy;
  1246.  
  1247.  while(1)
  1248.  {
  1249.   which=DoDialog(&AODd);
  1250.   switch(which)
  1251.   {
  1252.    case 0:    // ESC or EXIT
  1253.    case 3:
  1254.      return;
  1255.    //
  1256.    // ADD
  1257.    //
  1258.    case 1:
  1259.      which=DoDialog(&TOMd);
  1260.      if (!which)
  1261.        break;
  1262.  
  1263.      switch(which)
  1264.      {
  1265.       case 1:
  1266.     if (numtplanes==10)
  1267.       {
  1268.        ErrDialog("You already have 10 TILEINFO\n"
  1269.              "planes defined!"," OK ");
  1270.        return;
  1271.       }
  1272.     break;
  1273.  
  1274.       case 2:
  1275.     if (!tilemnum)
  1276.       {
  1277.        ErrDialog("You crazy shit! You don't\n"
  1278.              "have any masked tiles!"," Duh! ");
  1279.        return;
  1280.       }
  1281.  
  1282.     if (numtmplanes==10)
  1283.       {
  1284.        ErrDialog("You already have 10 TILEINFOM\n"
  1285.              "planes defined!"," OK ");
  1286.        return;
  1287.       }
  1288.     break;
  1289.      }
  1290.  
  1291.      DrawDialog(&NId,1);
  1292.      MouseHide();
  1293.      GetDialogXY(&NId,&dx,&dy);
  1294.      sx=dx+1;
  1295.      sy=dy+1;
  1296.      DrawBorder(sx,sy,9,2,1);
  1297.      sx=dx+2;
  1298.      sy=dy+2;
  1299.      if (!input(temp,7))
  1300.        {
  1301.     RestoreBackground();
  1302.     MouseShow();
  1303.     break;
  1304.        }
  1305.  
  1306.      //
  1307.      // MOVE THE NAME AND ALLOCATE THE MEMORY!
  1308.      //
  1309.      switch(which)
  1310.      {
  1311.       case 1:
  1312.     movedata(FP_SEG(temp),FP_OFF(temp),
  1313.          (unsigned)MapFileHeader,FP_OFF(MapFileHeader->tnames[numtplanes]),8);
  1314.     MMAllocate((memptr *)&Tinfo[numtplanes],tilenum);
  1315.     for (i=0;i<tilenum;i++)
  1316.       *(Tinfo[numtplanes]+i)=0;
  1317.     MapFileHeader->numtplanes=++numtplanes;
  1318.     writeH=DirtyFlag=1;
  1319.     break;
  1320.  
  1321.       case 2:
  1322.     movedata(FP_SEG(temp),FP_OFF(temp),
  1323.          (unsigned)MapFileHeader,FP_OFF(MapFileHeader->tmnames[numtmplanes]),8);
  1324.     MMAllocate((memptr *)&TMinfo[numtmplanes],tilemnum);
  1325.     for (i=0;i<tilemnum;i++)
  1326.       *(TMinfo[numtmplanes]+i)=0;
  1327.     MapFileHeader->numtmplanes=++numtmplanes;
  1328.     writeH=DirtyFlag=1;
  1329.      }
  1330.  
  1331.      RestoreBackground();
  1332.      MouseShow();
  1333.      break;
  1334.  
  1335.    //
  1336.    // DELETE
  1337.    //
  1338.    case 2:
  1339.      {
  1340.       unsigned ox,oy,i,oktoexit=0;
  1341.       int which;
  1342.  
  1343.       redo:
  1344.  
  1345.       MouseHide();
  1346.       DrawDialog(&TINd2,1);
  1347.       GetDialogXY(&TINd2,&sx,&sy);
  1348.       ox=sx;
  1349.       oy=sy;
  1350.       DrawBorder(sx,sy+2,10,11,1);
  1351.       sx=ox;
  1352.       sy=oy;
  1353.       DrawBorder(sx+11,sy+2,10,11,1);
  1354.  
  1355.       for (i=0;i<10;i++)
  1356.       {
  1357.        sx=ox+1;
  1358.        sy=oy+i+3;
  1359.        fprint(MapFileHeader->tnames[i]);
  1360.        sx=ox+12;
  1361.        sy=oy+i+3;
  1362.        fprint(MapFileHeader->tmnames[i]);
  1363.       }
  1364.       MouseShow();
  1365.  
  1366.       do
  1367.       {
  1368.        if ((which=CheckList(ox+1,oy+3,8,numtplanes,TInfoNon,TInfoNoff,0))>=0)
  1369.      {
  1370.       int reply;
  1371.  
  1372.       RestoreBackground();
  1373.       reply=DoDialog(&AreSureD2);
  1374.       switch(reply)
  1375.       {
  1376.        case 0:
  1377.        case 2:
  1378.          goto redo;
  1379.       }
  1380.  
  1381.       if (which!=numtplanes-1)
  1382.         {
  1383.          for (i=0;i<8;i++)
  1384.            {
  1385.         MapFileHeader->tnames[which][i]=MapFileHeader->tnames[numtplanes-1][i];
  1386.         MapFileHeader->tnames[numtplanes-1][i]=0;
  1387.            }
  1388.          for (i=0;i<tilenum;i++)
  1389.            *(Tinfo[which]+i)=*(Tinfo[numtplanes-1]+i);
  1390.          MMFreePtr((memptr *)&Tinfo[numtplanes-1]);
  1391.         }
  1392.       else
  1393.         {
  1394.          MMFreePtr((memptr *)&Tinfo[which]);
  1395.          for (i=0;i<8;i++)
  1396.            MapFileHeader->tnames[which][i]=0;
  1397.         }
  1398.       writeH=DirtyFlag=1;
  1399.       MapFileHeader->numtplanes=--numtplanes;
  1400.       goto redo;
  1401.      }
  1402.  
  1403.        if ((which=CheckList(ox+12,oy+3,8,numtmplanes,TInfoMNon,TInfoMNoff,0))>=0)
  1404.      {
  1405.       int reply;
  1406.  
  1407.       RestoreBackground();
  1408.       reply=DoDialog(&AreSureD2);
  1409.       switch(reply)
  1410.       {
  1411.        case 0:
  1412.        case 2:
  1413.          goto redo;
  1414.       }
  1415.  
  1416.       if (which!=numtmplanes-1)
  1417.         {
  1418.          for (i=0;i<8;i++)
  1419.            {
  1420.         MapFileHeader->tmnames[which][i]=MapFileHeader->tmnames[numtplanes-1][i];
  1421.         MapFileHeader->tmnames[numtmplanes-1][i]=0;
  1422.            }
  1423.          for (i=0;i<tilemnum;i++)
  1424.            *(TMinfo[which]+i)=*(TMinfo[numtmplanes-1]+i);
  1425.          MMFreePtr((memptr *)&TMinfo[numtmplanes-1]);
  1426.         }
  1427.       else
  1428.         {
  1429.          MMFreePtr((memptr *)&TMinfo[which]);
  1430.          for (i=0;i<8;i++)
  1431.            MapFileHeader->tmnames[which][i]=0;
  1432.         }
  1433.       writeH=DirtyFlag=1;
  1434.       MapFileHeader->numtmplanes=--numtmplanes;
  1435.       goto redo;
  1436.      }
  1437.  
  1438.        GetButtonXY(&TINd2,0,&sx,&sy);
  1439.        if (!CheckList(sx,sy,6,1,TIDoneOn,TIDoneOff,1))
  1440.      oktoexit++;
  1441.  
  1442.        if (keydown[1])
  1443.      {
  1444.       while(keydown[1]);
  1445.       oktoexit++;
  1446.      }
  1447.       }while(!oktoexit);
  1448.  
  1449.       RestoreBackground();
  1450.      }
  1451.   }
  1452.  }
  1453. }
  1454.  
  1455.  
  1456.  
  1457. ////////////////////////////////////////////////////
  1458. //
  1459. // Item - Project Re-Select
  1460. //
  1461. ////////////////////////////////////////////////////
  1462. btype NGBb[]={{" Do It! ",1,4,2},
  1463.           {" No! Help! ",16,4,1}};
  1464. DialogDef NGBd={"Are you sure you want to\n"
  1465.         "switch projects? Abort now\n"
  1466.         "or forever hold your peace!",
  1467.         28,6,2,&NGBb[0],NULL};
  1468.  
  1469. void Item_ProjectReSelect(void)
  1470. {
  1471.  int i,which;
  1472.  
  1473.  //
  1474.  // ARE YOU SURE?!
  1475.  //
  1476.  which=DoDialog(&NGBd);
  1477.  if (!which || which==2)
  1478.    return;
  1479.  
  1480.  
  1481.  TEDInfo->lastvid=videomode;
  1482.  TEDInfo->level=whichmap;
  1483.  SaveTEDInfo();
  1484.  SaveOutputHeader();
  1485.  
  1486.  if (!CheckForMapSave())
  1487.    return;
  1488.  
  1489.  //
  1490.  // RELEASE ALL MEMORY
  1491.  //         ---
  1492.  if (MapBkgnd)
  1493.    {
  1494.     MMFreePtr((memptr *)&MapBkgnd);
  1495.     MMFreePtr((memptr *)&CutBkgnd);
  1496.    }
  1497.  if (MapFrgnd)
  1498.    {
  1499.     MMFreePtr((memptr *)&MapFrgnd);
  1500.     MMFreePtr((memptr *)&CutFrgnd);
  1501.    }
  1502.  if (MapInfoPl)
  1503.    {
  1504.     MMFreePtr((memptr *)&MapInfoPl);
  1505.     MMFreePtr((memptr *)&CutInfoPl);
  1506.    }
  1507.  
  1508.  MMFreePtr((memptr *)&TEDInfo);
  1509.  MMFreePtr((memptr *)&MapFileHeader);
  1510.  
  1511.  if (CgaXMS)
  1512.    {
  1513.     MMFreePtr((memptr *)&CgaXMSlookup);
  1514.     XMSFreeMem(CgaXMS);
  1515.    }
  1516.  if (EgaXMS)
  1517.    {
  1518.     MMFreePtr((memptr *)&EgaXMSlookup);
  1519.     XMSFreeMem(EgaXMS);
  1520.    }
  1521.  if (VgaXMS)
  1522.    {
  1523.     MMFreePtr((memptr *)&VgaXMSlookup);
  1524.     XMSFreeMem(VgaXMS);
  1525.    }
  1526.  if (XMSmaps)
  1527.    XMSFreeMem(XMSmaps);
  1528.  
  1529.  XMSmaps=CgaXMS=EgaXMS=VgaXMS=xmshandle=0;
  1530.  
  1531.  
  1532.  for (i=0;i<numtplanes;i++)
  1533.    if (Tinfo[i])
  1534.      MMFreePtr((memptr *)&Tinfo[i]);
  1535.  for (i=0;i<numtmplanes;i++)
  1536.    if (TMinfo[i])
  1537.      MMFreePtr((memptr *)&TMinfo[i]);
  1538.  
  1539.  //
  1540.  // FORCE RE-INIT
  1541.  //
  1542.  writeH=TIxbase=TIxmbase=TIybase=TIymbase=PasteOK=DirtyFlag=ext[0]=0;
  1543.  lastmap=-1;
  1544.  
  1545.  FindGraphFile();
  1546.  LoadInfoFile();
  1547.  LoadMapHeader();
  1548.  LoadGraphStuff(0,videomode);
  1549.  MouseHide();
  1550.  RedrawDesktop();
  1551.  MouseShow();
  1552.  DrawInfoBar();
  1553.  DrawMap();
  1554. }
  1555.  
  1556.  
  1557. ////////////////////////////////////////////////////
  1558. //
  1559. // Item - Toggle GRIDMODE on/off
  1560. //
  1561. ////////////////////////////////////////////////////
  1562. void Item_GridMode(void)
  1563. {
  1564.  GridMode^=1;
  1565.  
  1566.  if (PasteMode)
  1567.    DrawFloatPaste();
  1568.  
  1569.  DrawMap();
  1570.  DrawInfoBar();
  1571. }
  1572.  
  1573.  
  1574. ////////////////////////////////////////////////////
  1575. //
  1576. // Item - Toggle SNAP-PASTE on/off
  1577. //
  1578. ////////////////////////////////////////////////////
  1579. void Item_SnapTog(void)
  1580. {
  1581.  if (!PasteMode)
  1582.    return;
  1583.  
  1584.  EraseFloatPaste();
  1585.  SnapMode^=1;
  1586.  
  1587.  snapx=(pixelx>>(tsize+2))+xbase;
  1588.  snapy=((pixely-8)>>(tsize+2))+ybase;
  1589.  snapxsize=TileCopy.w;
  1590.  snapysize=TileCopy.h;
  1591.  
  1592.  snapx=snapx-(snapx/snapxsize)*snapxsize;
  1593.  snapy=snapy-(snapy/snapysize)*snapysize;
  1594.  
  1595.  DrawInfoBar();
  1596.  DrawFloatPaste();
  1597. }
  1598.  
  1599.  
  1600. ////////////////////////////////////////////////////
  1601. //
  1602. // Item - View Map & Goto
  1603. //
  1604. ////////////////////////////////////////////////////
  1605. void Item_ViewMap(void)
  1606. {
  1607.  Do_ViewMap(0);
  1608. }
  1609.  
  1610.  
  1611. ////////////////////////////////////////////////////
  1612. //
  1613. // Item - Review Map & Goto
  1614. //
  1615. ////////////////////////////////////////////////////
  1616. void Item_ReviewMap(void)
  1617. {
  1618.  Do_ViewMap(1);
  1619. }
  1620.  
  1621.  
  1622. ////////////////////////////////////////////////////
  1623. //
  1624. // Code to actually do the ViewMap (and save it in
  1625. // EGA memory when finished).
  1626. // Entry:
  1627. // 0 = ViewMap, as normal & save when done (but only
  1628. //    if a full map was viewed)
  1629. // 1 = RestoreMap for GOTO
  1630. //
  1631. ////////////////////////////////////////////////////
  1632. void Do_ViewMap(int how)
  1633. {
  1634.  int _seg *a_bg,_seg *a_fg,_seg *a_in,CopyArea,bl_width,bl_height,bl_x,bl_y,p_info;
  1635.  
  1636.  char huge *EGA=MK_FP(0xa000,0);
  1637.  char _seg *block,_seg *gblock[4];
  1638.  int i,j,k,m,n,pwidth,lwidth,maptype,step,pixnum[4]={0,8,16,32},curpix,
  1639.       maxpack,curline,lybase,t8=8<<(tsize-1),t1=1<<(tsize-1),scrn_h,scrn_w;
  1640.  long tilelen,bufsize;
  1641.  int savevideo;
  1642.  
  1643.  
  1644.  
  1645.  savevideo=videomode;
  1646.  MouseHide();
  1647.  setvideo(EGA1);
  1648.  MouseShow();
  1649.  if (videomode!=EGA1 && videomode!=EGA2)
  1650.  {
  1651.   ErrDialog("This function is currently\n"
  1652.          "only usable in EGA mode!"," OK ");
  1653.   return;
  1654.  }
  1655.  
  1656.  //
  1657.  // SCREEN DIMENSIONS
  1658.  //
  1659.  scrn_w=320;
  1660.  scrn_h=200;
  1661.  
  1662.  
  1663.  bl_x=bl_y=0;
  1664.  bl_width=mapwidth;
  1665.  bl_height=mapheight;
  1666.  a_bg=MapBkgnd;
  1667.  a_fg=MapFrgnd;
  1668.  a_in=MapInfoPl;
  1669.  p_info=MapFileHeader->maptype;
  1670.  CopyArea=0;
  1671.  
  1672.  if ((TileCopy.w>screenw || TileCopy.h>screenh) && !how)
  1673.     if (Message("\"Yes\" to display full map,\n"
  1674.              "\"No\" to display COPY buffer.")==1)
  1675.     {
  1676.      bl_x=TileCopy.x;
  1677.      bl_y=TileCopy.y;
  1678.      bl_width=TileCopy.w;
  1679.      bl_height=TileCopy.h;
  1680.      a_bg=CutBkgnd;
  1681.      a_fg=CutFrgnd;
  1682.      a_in=CutInfoPl;
  1683.      p_info=TileCopy.PlanesCopied;
  1684.      CopyArea=1;
  1685.     }
  1686.  
  1687.  //
  1688.  // VALIDATE WIDTH & HEIGHT
  1689.  //
  1690.  if (bl_height<screenh && bl_width<screenw)
  1691.  {
  1692.   ErrDialog("The area fits within the\n"
  1693.          "screen! Forget it!"," Wah! ");
  1694.   return;
  1695.  }
  1696.  
  1697.  
  1698.  //
  1699.  // FIGURE OUT THE BEST RATIO FOR CONVERSION
  1700.  //
  1701.  if (!how)
  1702.     switch(bl_width>=bl_height)
  1703.     {
  1704.      case 1: // WIDTH > HEIGHT
  1705.         step=(float)(pixnum[tsize]*bl_width)/scrn_w+.5;
  1706.         if (pixnum[tsize]*bl_width/step>scrn_w)
  1707.     step++;
  1708.         if ((float)(pixnum[tsize]*bl_height)/step+.5<scrn_h)
  1709.     break;
  1710.  
  1711.      case 0: // HEIGHT > WIDTH
  1712.         step=(float)(pixnum[tsize]*bl_height)/scrn_h+.5;
  1713.         if (pixnum[tsize]*bl_height/step>scrn_h)
  1714.     step++;
  1715.     }
  1716.  else
  1717.     step=VMapData.step;
  1718.  
  1719.  
  1720.  //
  1721.  // POP LAST MAP ON SCREEN
  1722.  //
  1723.  if (how)
  1724.  {
  1725.   unsigned EGAseg=VMapData.EGAseg;
  1726.  
  1727.   if (!VMapData.built_flag)
  1728.   {
  1729.     ErrDialog("You haven't previously\n"
  1730.           "VIEWed a map!"," OK ");
  1731.     return;
  1732.   }
  1733.  
  1734.   //
  1735.   // RESTORE MAP IN MEMORY!
  1736.   //
  1737.   MouseHide();
  1738.   outport(GCindex,GCmode | 0x100);
  1739.   outport(SCindex,SCmapmask | 0xf00);
  1740.   asm    push    ds
  1741.   asm    mov    ax,[EGAseg]
  1742.   asm    mov    ds,ax
  1743.   asm    mov    ax,0xa000
  1744.   asm    mov    es,ax
  1745.   asm    xor    si,si
  1746.   asm    xor    di,di
  1747.   asm    mov    cx,0x2000
  1748.   asm    rep movsb
  1749.   asm    pop    ds
  1750.   step=VMapData.step;
  1751.   maxpack=VMapData.maxpack;
  1752.   MouseShow();
  1753.  }
  1754.  //
  1755.  // BUILD MAP
  1756.  //
  1757.  else
  1758.  {
  1759.   //
  1760.   // CLEAR EGA SCREEN
  1761.   //
  1762.   outport(GCindex,GCmode);
  1763.   outport(SCindex,SCmapmask | 0xf00);
  1764.   _fmemset(MK_FP(0xa000,0),0,0x2000);
  1765.  
  1766.   //
  1767.   // SET TILE LENGTH
  1768.   //
  1769.   switch(tsize)
  1770.   {
  1771.     case 1: tilelen=32L; break;
  1772.     case 2: tilelen=128L; break;
  1773.     case 3: tilelen=512L;
  1774.   }
  1775.  
  1776.   //
  1777.   // ALLOCATE TEMP BUFFERS & BEGIN!
  1778.   //
  1779.   bufsize=tilelen*bl_width;
  1780.   pwidth=t1*bl_width;
  1781.   lwidth=pwidth*4;
  1782.   MMAllocate((memptr *)&block,bufsize);
  1783.   maxpack=pwidth/step+1;
  1784.   for (i=0;i<4;i++)
  1785.      MMAllocate((memptr *)&gblock[i],maxpack);
  1786.  
  1787.   outport(GCindex,GCmode);
  1788.   curline=0;
  1789.   for (j=bl_y;j<bl_y+bl_height;j++)
  1790.   {
  1791.     lybase=j*t8;
  1792.     for (i=bl_x;i<bl_x+bl_width;i++)
  1793.     {
  1794.      unsigned tilet,tilem,tilei,loc;
  1795.  
  1796.      //
  1797.      // ESC out?
  1798.      //
  1799.      if (keydown[1])
  1800.      {
  1801.       while(keydown[1]);
  1802.       setvideo(savevideo);
  1803.       RedrawDesktop();
  1804.       DrawMap();
  1805.       DrawInfoBar();
  1806.       return;
  1807.      }
  1808.      //
  1809.      // GET THE CORRECT TILE MOVED INTO "TDATA"
  1810.      //
  1811.      loc=j*mapwidth+i;
  1812.      tilet=viewton?((p_info&BPLANE)?a_bg[loc]:-BkgndColor):-BkgndColor;
  1813.      tilem=viewmon?((p_info&FPLANE)?a_fg[loc]+tilenum:0):0;
  1814.      tilei=viewion?((p_info&IPLANE)?a_in[loc]+tilenum:0):0;
  1815.      CombineTiles(tilet,tilem,tilei,tsize);
  1816.  
  1817.      //
  1818.      // NOW, MUNGE "TDATA" INTO BIT-PLANES!
  1819.      //
  1820.      // INTERNAL:        P0    P1    P2    P3
  1821.      //    SCANLINE x    ......    ......    ......    ......
  1822.      //
  1823.      for (k=0;k<t8;k++)
  1824.         if (!((lybase+k)%step))
  1825.     for (m=0;m<4;m++)
  1826.       movedata(FP_SEG(&tdata),FP_OFF(&tdata)+(m*tsize*t8)+k*t1,
  1827.              (unsigned)block,k*lwidth+m*pwidth+(i-bl_x)*t1,t1);
  1828.     }
  1829.  
  1830.     //
  1831.     // CONVERT BIT-PLANE LINES TO COMPRESSED FORM...
  1832.     //
  1833.     for (k=0;k<8<<(tsize-1);k++)
  1834.     {
  1835.      if (!((lybase+k)%step))
  1836.      {
  1837.       int midx=k*lwidth;
  1838.  
  1839.  
  1840.       curpix=0;
  1841.       _fmemset(gblock[0],0,maxpack);
  1842.       _fmemset(gblock[1],0,maxpack);
  1843.       _fmemset(gblock[2],0,maxpack);
  1844.       _fmemset(gblock[3],0,maxpack);
  1845.       for (m=0;m<pwidth*8;m++)
  1846.       {
  1847.         if (!(m%step))
  1848.         {
  1849.          int temp=curpix/8,
  1850.         temp1=7-(curpix%8),
  1851.         temp2=7-(m%8),
  1852.         idx;
  1853.  
  1854.  
  1855.          idx=midx+m/8;
  1856.  
  1857.          #if 1
  1858.          asm    push    ds
  1859.  
  1860.          asm    mov    ds,[block]
  1861.          asm    mov    si,[idx]
  1862.          asm    mov    cl,[BYTE PTR temp2]
  1863.          asm    mov    ch,[BYTE PTR temp1]
  1864.          asm    mov    di,[temp]
  1865.          asm    mov    dx,[pwidth]
  1866.          asm    dec    dx
  1867.  
  1868.          asm    mov    es,[WORD PTR gblock]
  1869.  
  1870.          asm    lodsb
  1871.          asm    shr    al,cl
  1872.          asm    and    al,1
  1873.          asm    xchg    ch,cl
  1874.          asm    shl    al,cl
  1875.          asm    xchg    ch,cl
  1876.          asm    or    [es:di],al
  1877.  
  1878.          asm    add    si,dx
  1879.  
  1880.          asm    mov    es,[WORD PTR gblock+2]
  1881.  
  1882.          asm    lodsb
  1883.          asm    shr    al,cl
  1884.          asm    and    al,1
  1885.          asm    xchg    ch,cl
  1886.          asm    shl    al,cl
  1887.          asm    xchg    ch,cl
  1888.          asm    or    [es:di],al
  1889.  
  1890.          asm    add    si,dx
  1891.  
  1892.          asm    mov    es,[WORD PTR gblock+4]
  1893.  
  1894.          asm    lodsb
  1895.          asm    shr    al,cl
  1896.          asm    and    al,1
  1897.          asm    xchg    ch,cl
  1898.          asm    shl    al,cl
  1899.          asm    xchg    ch,cl
  1900.          asm    or    [es:di],al
  1901.  
  1902.          asm    add    si,dx
  1903.  
  1904.          asm    mov    es,[WORD PTR gblock+6]
  1905.  
  1906.          asm    lodsb
  1907.          asm    shr    al,cl
  1908.          asm    and    al,1
  1909.          asm    xchg    ch,cl
  1910.          asm    shl    al,cl
  1911.          asm    xchg    ch,cl
  1912.          asm    or    [es:di],al
  1913.  
  1914.          asm    add    si,dx
  1915.  
  1916.          asm    pop    ds
  1917.  
  1918.          #else
  1919.          *(gblock[0]+temp)|=((block[idx]>>temp2)&1)<<temp1;
  1920.          *(gblock[1]+temp)|=((block[idx+pwidth]>>temp2)&1)<<temp1;
  1921.          *(gblock[2]+temp)|=((block[idx+pwidth*2]>>temp2)&1)<<temp1;
  1922.          *(gblock[3]+temp)|=((block[idx+pwidth*3]>>temp2)&1)<<temp1;
  1923.          #endif
  1924.  
  1925.          curpix++;
  1926.         }
  1927.       }
  1928.  
  1929.       //
  1930.       // BLAST ONTO THE SCREEN
  1931.       //
  1932.  
  1933.       MouseHide();
  1934.       for (n=0;n<4;n++)
  1935.       {
  1936.         outport(SCindex,SCmapmask | (0x100<<n));
  1937.         for (m=0;m<maxpack;m++)
  1938.     *(EGA+EGA1lookup[curline]+m)=*(gblock[n]+m);
  1939.      }
  1940.      MouseShow();
  1941.  
  1942.      curline++;
  1943.     }
  1944.    }
  1945.   }
  1946.  
  1947.   MMFreePtr((memptr *)&block);
  1948.   for(m=0;m<4;m++)
  1949.     MMFreePtr((memptr *)&gblock[m]);
  1950.  
  1951.  
  1952.   //
  1953.   // SAVE MAP IN MEMORY!
  1954.   //
  1955.   if (!CopyArea)
  1956.   {
  1957.    unsigned EGAseg=0xa800;
  1958.  
  1959.  
  1960.    MouseHide();
  1961.    outport(GCindex,GCmode | 0x100);
  1962.    outport(SCindex,SCmapmask | 0xf00);
  1963.    asm    push    ds
  1964.    asm    mov    ax,[EGAseg]
  1965.    asm    mov    es,ax
  1966.    asm    mov    ax,0xa000
  1967.    asm    mov    ds,ax
  1968.    asm    xor    si,si
  1969.    asm    xor    di,di
  1970.    asm    mov    cx,0x2000
  1971.    asm    rep movsb
  1972.    asm    pop    ds
  1973.    VMapData.step=step;
  1974.    VMapData.built_flag=1;
  1975.    VMapData.EGAseg=EGAseg;
  1976.    VMapData.maxpack=maxpack;
  1977.    MouseShow();
  1978.   }
  1979.  }
  1980.  
  1981.  
  1982.  //
  1983.  // DONE WITH MAP BUILD-N-DISPLAY
  1984.  //
  1985.  SignalSound();
  1986.  clearkeys();
  1987.  
  1988.  //
  1989.  // IF MOUSE BUTTON PRESSED WITHIN REGION, GO THERE!
  1990.  //
  1991.  while(!bioskey(1))
  1992.    if (MouseButton())
  1993.    {
  1994.     int x,y;
  1995.  
  1996.     MouseCoords(&x,&y);
  1997.     if (x<maxpack*8 && y<(mapheight*t8/step) && !CopyArea)
  1998.     {
  1999.      xbase=(x*step)/t8-screenw/2;
  2000.      ybase=(y*step)/t8-screenh/2;
  2001.      if (xbase+screenw>mapwidth)
  2002.        xbase=mapwidth-screenw;
  2003.      if (ybase+screenh>mapheight)
  2004.        ybase=mapheight-screenh;
  2005.      if (xbase<0)
  2006.        xbase=0;
  2007.      if (ybase<0)
  2008.        ybase=0;
  2009.     }
  2010.     while(MouseButton());
  2011.     break;
  2012.    }
  2013.  
  2014.  clearkeys();
  2015.  MouseHide();
  2016.  setvideo(savevideo);
  2017.  RedrawDesktop();
  2018.  DrawMap();
  2019.  DrawInfoBar();
  2020.  MouseShow();
  2021. }
  2022.  
  2023.  
  2024. ////////////////////////////////////////////////////
  2025. //
  2026. // MAP IMPORTING FUNCTIONS FOLLOW:
  2027. //
  2028. ////////////////////////////////////////////////////
  2029. char _seg *oldnames,oldmapname[64],oldmapheadname[64],
  2030.     oldSM_name[64],oldSM_loadname[64];
  2031.  
  2032. int IM_swapin(void)
  2033. {
  2034.  int i;
  2035.  
  2036.  
  2037.  _fstrcpy(mapheadname,TEDInfo->ImportPath);
  2038.  strcat(mapheadname,oldmapheadname);
  2039.  if (access(mapheadname,0))
  2040.    {
  2041.     strcpy(mapheadname,oldmapheadname);
  2042.     return 0;
  2043.    }
  2044.  
  2045.  _fstrcpy(mapname,TEDInfo->ImportPath);
  2046.  strcat(mapname,oldmapname);
  2047.  
  2048.  
  2049.  _fstrcpy(SM_name,TEDInfo->ImportPath);
  2050.  strcat(SM_name,oldSM_name);
  2051.  
  2052.  _fstrcpy(SM_loadname,TEDInfo->ImportPath);
  2053.  strcat(SM_loadname,oldSM_loadname);
  2054.  
  2055.  MMAllocate((memptr *)&oldnames,100*16);
  2056.  movedata(FP_SEG(MapNames),FP_OFF(MapNames),(unsigned)oldnames,0,100*16);
  2057.  
  2058.  MMFreePtr((memptr *)&MapFileHeader);
  2059.  
  2060.  LoadIn(mapheadname,(memptr *)&MapFileHeader);
  2061.  
  2062.  for (i=0;i<100;i++)
  2063.    if (MapFileHeader->dataoffsets[i]>=0)
  2064.    {
  2065.     MapHeaderStr TempHead;
  2066.  
  2067.     LoadFile(mapname,(char huge *)&TempHead,MapFileHeader->dataoffsets[i],sizeof(MapHeaderStr));
  2068.     strcpy(MapNames[i],TempHead.name);
  2069.    }
  2070.  return 1;
  2071. }
  2072.  
  2073.  
  2074. void IM_swapout(void)
  2075. {
  2076.  if (oldnames)        // GET RID OF MAPNAMES
  2077.  {
  2078.   strcpy(mapname,oldmapname);
  2079.   strcpy(mapheadname,oldmapheadname);
  2080.   strcpy(SM_name,oldSM_name);
  2081.   strcpy(SM_loadname,oldSM_loadname);
  2082.  
  2083.   movedata((unsigned)oldnames,0,FP_SEG(MapNames),FP_OFF(MapNames),100*16);
  2084.   MMFreePtr((memptr *)&oldnames);
  2085.   MMFreePtr((memptr *)&MapFileHeader);
  2086.   LoadIn(mapheadname,(memptr *)&MapFileHeader);
  2087.  
  2088.  }
  2089. }
  2090.  
  2091. void IM_LoadMap(void)
  2092. {
  2093.  unsigned long csize,size=0;
  2094.  memptr block;
  2095.  
  2096.  //
  2097.  // DEALLOCATE ALL CURRENT MAP MEMORY
  2098.  //
  2099.  if (MapBkgnd)
  2100.    {
  2101.     MMFreePtr((memptr *)&MapBkgnd);
  2102.     MMFreePtr((memptr *)&CutBkgnd);
  2103.    }
  2104.  if (MapFrgnd)
  2105.    {
  2106.     MMFreePtr((memptr *)&MapFrgnd);
  2107.     MMFreePtr((memptr *)&CutFrgnd);
  2108.    }
  2109.  if (MapInfoPl)
  2110.    {
  2111.     MMFreePtr((memptr *)&MapInfoPl);
  2112.     MMFreePtr((memptr *)&CutInfoPl);
  2113.    }
  2114.  
  2115.  //
  2116.  // LOAD MAP HEADER
  2117.  //
  2118.  LoadFile(mapname,(char huge *)&MapHeader,MapFileHeader->dataoffsets[whichmap],sizeof(MapHeaderStr));
  2119.  
  2120.  //
  2121.  // LOAD & DECOMPRESS MAP PLANES
  2122.  //
  2123.  if (MapFileHeader->maptype & BPLANE)
  2124.    {
  2125.     LoadFile(mapname,(char huge *)&size,MapHeader.mapbkgndpl,2);
  2126.  
  2127.     MMAllocate((memptr *)&MapBkgnd,size);
  2128.     MMAllocate((memptr *)&CutBkgnd,size);
  2129.     csize=MapHeader.mapbkgndlen-2;
  2130.     MMAllocate(&block,csize);
  2131.  
  2132.     LoadFile(mapname,MK_FP(block,0),MapHeader.mapbkgndpl+2,csize);
  2133.  
  2134.     RLEWExpand(MK_FP(block,0),MK_FP(MapBkgnd,0),size,MapFileHeader->RLEWtag);
  2135.     MMFreePtr(&block);
  2136.    }
  2137.  if (MapFileHeader->maptype & FPLANE)
  2138.    {
  2139.     LoadFile(mapname,(char huge *)&size,MapHeader.mapfrgndpl,2);
  2140.  
  2141.     MMAllocate((memptr *)&MapFrgnd,size);
  2142.     MMAllocate((memptr *)&CutFrgnd,size);
  2143.     csize=MapHeader.mapfrgndlen-2;
  2144.     MMAllocate(&block,csize);
  2145.  
  2146.     LoadFile(mapname,MK_FP(block,0),MapHeader.mapfrgndpl+2,csize);
  2147.  
  2148.     RLEWExpand(MK_FP(block,0),MK_FP(MapFrgnd,0),size,MapFileHeader->RLEWtag);
  2149.     MMFreePtr(&block);
  2150.    }
  2151.  if (MapFileHeader->maptype & IPLANE)
  2152.    {
  2153.     LoadFile(mapname,(char huge *)&size,MapHeader.mapinfopl,2);
  2154.  
  2155.     MMAllocate((memptr *)&MapInfoPl,size);
  2156.     MMAllocate((memptr *)&CutInfoPl,size);
  2157.     csize=MapHeader.mapinfolen-2;
  2158.     MMAllocate(&block,csize);
  2159.  
  2160.     LoadFile(mapname,MK_FP(block,0),MapHeader.mapinfopl+2,csize);
  2161.  
  2162.     RLEWExpand(MK_FP(block,0),MK_FP(MapInfoPl,0),size,MapFileHeader->RLEWtag);
  2163.     MMFreePtr(&block);
  2164.    }
  2165. }
  2166.  
  2167.  
  2168. void IM_SaveMap(void)
  2169. {
  2170.  memptr block;
  2171.  long fsize,size,nsize,change;
  2172.  MapHeaderStr TempHeader;
  2173.  int i,XMStemp;
  2174.  char string[100],TEDid[]=IDSTRING;
  2175.  
  2176.  
  2177.  
  2178.  strcpy(string,"Saving Map, '");
  2179.  strcat(string,MapHeader.name);
  2180.  
  2181.  strcat(string,"'.");
  2182.  ErrDialog(string,"");
  2183.  
  2184.  //
  2185.  // SAVE MAP FILE HEADER
  2186.  //
  2187.  SaveFile(mapheadname,MK_FP(MapFileHeader,0),0,sizeof(MapFileHeaderStr));
  2188.  fsize=sizeof(MapFileHeaderStr);
  2189.  
  2190.  //
  2191.  // COMPRESS & SAVE TILEINFOS
  2192.  //
  2193.  for (i=0;i<numtplanes;i++)
  2194.    {
  2195.     MMAllocate(&block,tilenum);
  2196.     MapFileHeader->tileinfooff[i]=fsize;
  2197.     nsize=RLEBCompress(MK_FP(Tinfo[i],0),tilenum,MK_FP(block,0),MapFileHeader->RLEWtag);
  2198.     MapFileHeader->tileinfolen[i]=nsize;
  2199.     SaveFile(mapheadname,MK_FP(block,0),fsize,nsize);
  2200.     fsize+=nsize;
  2201.     MMFreePtr(&block);
  2202.    }
  2203.  
  2204.  for (i=0;i<numtmplanes;i++)
  2205.    {
  2206.     MMAllocate(&block,tilemnum);
  2207.     MapFileHeader->tileinfomoff[i]=fsize;
  2208.     nsize=RLEBCompress(MK_FP(TMinfo[i],0),tilemnum,MK_FP(block,0),MapFileHeader->RLEWtag);
  2209.     MapFileHeader->tileinfomlen[i]=nsize;
  2210.     SaveFile(mapheadname,MK_FP(block,0),fsize,nsize);
  2211.     fsize+=nsize;
  2212.     MMFreePtr(&block);
  2213.    }
  2214.  
  2215.  MapFileHeader->oldtilenum=tilenum;
  2216.  MapFileHeader->oldtilemnum=tilemnum;
  2217.  
  2218.  SaveFile(mapheadname,MK_FP(MapFileHeader,2),2,sizeof(MapFileHeaderStr)-2);
  2219.  //
  2220.  // SAVE ALREADY COMPRESSED MAPS
  2221.  //
  2222.  
  2223.  //
  2224.  // NOTE: I AM STORING "TED5" AT THE START OF THE FILE BECAUSE
  2225.  // SAVING THE FILE AT OFFSET 0 WILL TRASH IT (I HAVE TO RE-SAVE THE HEADER!)
  2226.  //
  2227.  SaveFile(SM_name,(char huge *)TEDid,0,strlen(TEDid));
  2228.  fsize=strlen(TEDid);
  2229.  
  2230.  for (i=0;i<100;i++)
  2231.  {
  2232.   long oldoff;
  2233.  
  2234.   if (MapFileHeader->dataoffsets[i]==-1 || i==whichmap)
  2235.     continue;
  2236.  
  2237.   oldoff=MapFileHeader->dataoffsets[i];
  2238.  
  2239.   LoadFile(SM_loadname,(char huge *)&TempHeader,oldoff,sizeof(MapHeaderStr));
  2240.  
  2241.   strcpy(TempHeader.name,MapNames[i]);
  2242.   MapFileHeader->dataoffsets[i]=fsize;
  2243.   size=TempHeader.mapbkgndlen+TempHeader.mapfrgndlen+TempHeader.mapinfolen;
  2244.   change=TempHeader.mapbkgndpl-fsize-sizeof(MapHeaderStr);
  2245.   TempHeader.mapbkgndpl-=change;
  2246.   TempHeader.mapfrgndpl-=change;
  2247.   TempHeader.mapinfopl-=change;
  2248.  
  2249.   SaveFile(SM_name,(char huge *)&TempHeader,fsize,sizeof(MapHeaderStr));
  2250.   fsize+=sizeof(MapHeaderStr);
  2251.  
  2252.   MMAllocate(&block,size);
  2253.   LoadFile(SM_loadname,MK_FP(block,0),oldoff+sizeof(MapHeaderStr),size);
  2254.   SaveFile(SM_name,MK_FP(block,0),fsize,size);
  2255.   fsize+=size;
  2256.   SaveFile(SM_name,"!ID!",fsize,4);
  2257.   fsize+=4;
  2258.   MMFreePtr(&block);
  2259.  }
  2260.  
  2261.  //
  2262.  // SAVE CURRENT MAP AT END OF FILE
  2263.  //
  2264.  MapFileHeader->dataoffsets[whichmap]=fsize;
  2265.  MapFileHeader->datalengths[whichmap]=sizeof(MapHeaderStr);
  2266.  SaveFile(SM_name,(char huge *)&MapHeader,fsize,sizeof(MapHeaderStr));
  2267.  fsize+=sizeof(MapHeaderStr);
  2268.  
  2269.  size=MapHeader.width*MapHeader.height*sizeof(int);
  2270.  MMAllocate(&block,size);
  2271.  if (MapFileHeader->maptype & BPLANE)
  2272.    {
  2273.     MapHeader.mapbkgndpl=fsize;
  2274.     nsize=RLEWCompress(MK_FP(MapBkgnd,0),size,MK_FP(block,0),MapFileHeader->RLEWtag);
  2275.     MapHeader.mapbkgndlen=nsize+2;
  2276.  
  2277.     SaveFile(SM_name,(char huge *)&size,fsize,2);
  2278.     fsize+=2;
  2279.     SaveFile(SM_name,MK_FP(block,0),fsize,nsize);
  2280.     fsize+=nsize;
  2281.    }
  2282.  else
  2283.    MapHeader.mapbkgndlen=0;
  2284.  
  2285.  if (MapFileHeader->maptype & FPLANE)
  2286.    {
  2287.     MapHeader.mapfrgndpl=fsize;
  2288.     nsize=RLEWCompress(MK_FP(MapFrgnd,0),size,MK_FP(block,0),MapFileHeader->RLEWtag);
  2289.     MapHeader.mapfrgndlen=nsize+2;
  2290.  
  2291.     SaveFile(SM_name,(char huge *)&size,fsize,2);
  2292.     fsize+=2;
  2293.     SaveFile(SM_name,MK_FP(block,0),fsize,nsize);
  2294.     fsize+=nsize;
  2295.    }
  2296.  else
  2297.    MapHeader.mapfrgndlen=0;
  2298.  
  2299.  if (MapFileHeader->maptype & IPLANE)
  2300.    {
  2301.     MapHeader.mapinfopl=fsize;
  2302.     nsize=RLEWCompress(MK_FP(MapInfoPl,0),size,MK_FP(block,0),MapFileHeader->RLEWtag);
  2303.     MapHeader.mapinfolen=nsize+2;
  2304.  
  2305.     SaveFile(SM_name,(char huge *)&size,fsize,2);
  2306.     fsize+=2;
  2307.     SaveFile(SM_name,MK_FP(block,0),fsize,nsize);
  2308.     fsize+=nsize;
  2309.    }
  2310.  else
  2311.    MapHeader.mapinfolen=0;
  2312.  
  2313.  SaveFile(SM_name,"!ID!",fsize,4);
  2314.  
  2315.  fsize+=4;
  2316.  
  2317.  MMFreePtr(&block);
  2318.  
  2319.  // RE-SAVE HEADER
  2320.  SaveFile(SM_name,(char huge *)&MapHeader,
  2321.      MapFileHeader->dataoffsets[whichmap],sizeof(MapHeaderStr));
  2322.  
  2323.  //
  2324.  // RE-SAVE FILE HEADER
  2325.  // NOTE: The "2" is so MSDOS doesn't truncate the fucking file!
  2326.  //
  2327.  SaveFile(mapheadname,MK_FP(MapFileHeader,2),2,sizeof(MapFileHeaderStr)-2);
  2328.  
  2329.  unlink(SM_loadname);
  2330.  rename(SM_name,SM_loadname);
  2331.  
  2332.  RestoreBackground();
  2333. }
  2334.  
  2335.  
  2336. ////////////////////////////////////////////////////
  2337. //
  2338. // Item - Import Maps
  2339. //
  2340. ////////////////////////////////////////////////////
  2341. btype IMPMb[]={{"New Path",3,2,1},
  2342.            {" Import ",3,5,1},
  2343.            {"  Exit  ",3,8,2}};
  2344. DialogDef IMPMd={"Map Importing",13,11,3,&IMPMb[0],NULL};
  2345. btype NPb={"                                    ",1,3,1};
  2346. DialogDef NPd={"Current Path:",38,5,1,&NPb,NULL};
  2347.  
  2348.  
  2349. void Item_ImportMaps(void)
  2350. {
  2351.  char imfile[64],tempstr[40],impath[64];
  2352.  int oldwhichmap,which,mapnum,i;
  2353.  int oldxb,oldyb;
  2354.  
  2355.  
  2356.  CheckForMapSave();
  2357.  
  2358.  //
  2359.  // THE IMPORT FUNCTION WILL RID THE SYSTEM OF XMSMAPS
  2360.  //
  2361.  if (XMSmaps)
  2362.  {
  2363.   XMSFreeMem(XMSmaps);
  2364.   XMSmaps=0;
  2365.  }
  2366.  
  2367.  //
  2368.  // SAVE PATHS
  2369.  //
  2370.  _fstrcpy(impath,TEDInfo->ImportPath);
  2371.  
  2372.  strcpy(oldmapname,mapname);
  2373.  strcpy(oldmapheadname,mapheadname);
  2374.  strcpy(oldSM_name,SM_name);
  2375.  strcpy(oldSM_loadname,SM_loadname);
  2376.  
  2377.  oldxb=xbase;
  2378.  oldyb=ybase;
  2379.  #pragma warn -sus
  2380.  oldnames=0;
  2381.  #pragma warn +sus
  2382.  oldwhichmap=whichmap;
  2383.  
  2384.  DrawDialog(&IMPMd,1);
  2385.  while(1)
  2386.  {
  2387.   which=CheckButtons(&IMPMd);
  2388.   switch(which)
  2389.   {
  2390.    //
  2391.    // NEW PATH
  2392.    //
  2393.    case 1:
  2394.      MouseHide();
  2395.      DrawDialog(&NPd,1);
  2396.      GetDialogXY(&NPd,&sx,&sy);
  2397.      sy++;
  2398.      sx++;
  2399.      if (!impath[0])
  2400.        print("- current dir -");
  2401.      else
  2402.        print(impath);
  2403.      GetButtonXY(&NPd,0,&sx,&sy);
  2404.      if (input(tempstr,36))
  2405.        {
  2406.     strcpy(impath,tempstr);
  2407.     if (impath[strlen(impath)-1]!='\\')
  2408.       strcat(impath,"\\");
  2409.  
  2410.     MouseShow();
  2411.     if (access(mapheadname,0))
  2412.     {
  2413.      ErrDialog("Can't find any TED5\n"
  2414.            "map files at that path."," OK ");
  2415.     }
  2416.     else
  2417.     {
  2418.      RestoreBackground();
  2419.      ErrDialog("Verifying path...","");
  2420.      _fstrcpy(TEDInfo->ImportPath,impath);
  2421.      DirtyFlag=1;
  2422.     }
  2423.  
  2424.     MouseHide();
  2425.        }
  2426.      MouseShow();
  2427.      RestoreBackground();
  2428.      break;
  2429.  
  2430.    //
  2431.    // IMPORT
  2432.    //
  2433.    case 2:
  2434.      if (!oldnames)
  2435.      {
  2436.       ErrDialog("Loading File Info...","");
  2437.       if (!IM_swapin())
  2438.       {
  2439.        RestoreBackground();
  2440.        ErrDialog("Having problems with your path!"," OK ");
  2441.        break;
  2442.       }
  2443.       RestoreBackground();
  2444.      }
  2445.  
  2446.      mapnum=SelectMap(1,CREATED,"TO IMPORT");
  2447.      if (mapnum>=0)
  2448.      {
  2449.       char check[100]="Are you SURE you want to\n"
  2450.               "Import ";
  2451.  
  2452.       strcat(check,MapNames[mapnum]);
  2453.       strcat(check,"?");
  2454.       if (Message(check)<2)
  2455.     break;
  2456.  
  2457.       whichmap=mapnum;
  2458.       ErrDialog("Importing. One moment.","");
  2459.       IM_LoadMap();
  2460.       IM_swapout();
  2461.       IM_SaveMap();
  2462.       IM_swapin();
  2463.       RestoreBackground();
  2464.      }
  2465.      break;
  2466.  
  2467.    //
  2468.    // EXIT
  2469.    //
  2470.    case 0:
  2471.    case 3:
  2472.      RestoreBackground();
  2473.      whichmap=oldwhichmap;
  2474.      IM_swapout();
  2475.  
  2476.      LoadMap(whichmap);
  2477.      xbase=oldxb;
  2478.      ybase=oldyb;
  2479.      DrawMap();
  2480.  
  2481.      return;
  2482.   }
  2483.  }
  2484. }
  2485.  
  2486.  
  2487. ////////////////////////////////////////////////////
  2488. //
  2489. // Item - Visit DOS
  2490. //
  2491. ////////////////////////////////////////////////////
  2492. int olddisk;
  2493. char oldpath[64]="\\";
  2494.  
  2495. void Item_VisitDOS(void)
  2496. {
  2497.  TempStruct LaunchInfo;
  2498.  char ename[64],temp[40],tiname[14]="TEDINFO.TMP";
  2499.  
  2500.  long size;
  2501.  
  2502.  
  2503.  //
  2504.  // Save the handles for all XMS memory so we don't
  2505.  // have to re-install this shit!
  2506.  //
  2507.  TEDInfo->OldCgaXMS=CgaXMS;
  2508.  TEDInfo->OldEgaXMS=EgaXMS;
  2509.  TEDInfo->OldVgaXMS=VgaXMS;
  2510.  
  2511.  TEDInfo->OldCgaXMSsize=CgaXMSsize;
  2512.  TEDInfo->OldEgaXMSsize=EgaXMSsize;
  2513.  TEDInfo->OldVgaXMSsize=VgaXMSsize;
  2514.  
  2515.  size=4L*(tilenum+tilemnum);
  2516.  if (CgaXMS)
  2517.    {
  2518.     if (1024L*XMSTotalFree()<size)
  2519.       {
  2520.        XMSFreeMem(CgaXMS);
  2521.        TEDInfo->OldCgaXMS=TEDInfo->OldCgaXMSsize=0;
  2522.       }
  2523.     else
  2524.       {
  2525.        TEDInfo->CgaXMSlook=XMSAllocate(size);
  2526.        XMSmove(0,(long)MK_FP(CgaXMSlookup,0),TEDInfo->CgaXMSlook,0,size);
  2527.       }
  2528.    }
  2529.  
  2530.  if (EgaXMS)
  2531.    {
  2532.     if (1024L*XMSTotalFree()<size)
  2533.       {
  2534.        XMSFreeMem(EgaXMS);
  2535.        TEDInfo->OldEgaXMS=TEDInfo->OldEgaXMSsize=0;
  2536.       }
  2537.     else
  2538.       {
  2539.        TEDInfo->EgaXMSlook=XMSAllocate(size);
  2540.        XMSmove(0,(long)MK_FP(EgaXMSlookup,0),TEDInfo->EgaXMSlook,0,size);
  2541.       }
  2542.    }
  2543.  
  2544.  if (VgaXMS)
  2545.    {
  2546.     if (1024L*XMSTotalFree()<size)
  2547.       {
  2548.        XMSFreeMem(VgaXMS);
  2549.        TEDInfo->OldVgaXMS=TEDInfo->OldVgaXMSsize=0;
  2550.       }
  2551.     else
  2552.       {
  2553.        TEDInfo->VgaXMSlook=XMSAllocate(size);
  2554.        XMSmove(0,(long)MK_FP(VgaXMSlookup,0),TEDInfo->VgaXMSlook,0,size);
  2555.       }
  2556.    }
  2557.  
  2558.  //
  2559.  // SAVE CURRENT VIDEOMODE FOR LAUNCH RETURN
  2560.  //
  2561.  LaunchInfo.lastmode=videomode;
  2562.  strcpy(LaunchInfo.ext,ext);
  2563.  SaveFile(tiname,(char huge *)&LaunchInfo,0,sizeof(TempStruct));
  2564.  
  2565.  TEDInfo->oscrx=xbase;
  2566.  TEDInfo->oscry=ybase;
  2567.  _fmemcpy((void far *)TEDInfo->parmstring,(void far *)parmstring,64);
  2568.  
  2569.  Item_SaveMap();
  2570.  SaveTEDInfo();
  2571.  SaveOutputHeader();
  2572.  
  2573.  if (XMSmaps)
  2574.    XMSFreeMem(XMSmaps);
  2575.  
  2576.  strcpy(temp,"Launching ");
  2577.  _fstrcat((char far *)temp,(char far *)TEDInfo->launchname);
  2578.  strcat(temp,"...");
  2579.  ErrDialog(temp,"");
  2580.  clearkeys();
  2581.  nosound();
  2582.  MouseHide();
  2583.  
  2584.  _fmemcpy((char far *)ename,(char far *)TEDInfo->launchname,14);
  2585.  
  2586.  RemoveUndoBuffers();
  2587.  ShutdownKBD();
  2588.  
  2589.  //
  2590.  // ARE WE EXITING WITH A BATCH FILE?
  2591.  //
  2592.  
  2593.  setvideo(TEXT);
  2594.  printf("The TED5 DOS shell. Type 'EXIT' to return to TED5.");
  2595.  
  2596.  //
  2597.  // SAVE CURRENT DRIVE & PATH
  2598.  //
  2599.  olddisk=getdisk();
  2600.  getcurdir(0,oldpath+1);
  2601.  
  2602.  MMShutdown();
  2603.  fcloseall();
  2604.  spawnlp(P_WAIT,"COMMAND",NULL);
  2605.  
  2606.  //
  2607.  // RESET OLD PATH
  2608.  //
  2609.  setdisk(olddisk);
  2610.  chdir(oldpath);
  2611.  
  2612.  execlp("TED5.EXE","TED5.EXE","/LAUNCH",NULL);
  2613.  
  2614.  printf("Can't find TED5 for some reason!");
  2615.  exit(1);
  2616. }
  2617.  
  2618.  
  2619. ////////////////////////////////////////////////////
  2620. //
  2621. // Item - Paste Overlay toggle
  2622. //
  2623. ////////////////////////////////////////////////////
  2624. void Item_POtog(void)
  2625. {
  2626.  F3_flag^=1;
  2627.  
  2628.  if (PasteMode)
  2629.  {
  2630.   EraseFloatPaste();
  2631.   DrawFloatPaste();
  2632.  }
  2633. }
  2634.